package com.dragee.modules.sys.controller;

import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.dragee.common.Dic;
import com.dragee.common.PageUtils;
import com.dragee.common.R;
import com.dragee.common.VerifyParam;
import com.dragee.config.exception.BusinessException;
import com.dragee.constants.AuthConstants;
import com.dragee.modules.sys.dao.SysUserRoleMapper;
import com.dragee.modules.sys.entity.SysRole;
import com.dragee.modules.sys.entity.SysUserRole;
import com.dragee.modules.sys.entity.UserEntity;
import com.dragee.modules.sys.po.RolePo;
import com.dragee.modules.sys.service.ISysRoleService;
import com.dragee.modules.sys.service.UserRoleService;
import com.dragee.modules.sys.service.UserService;
import com.dragee.utils.LoginUserUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.Data;
import org.apache.shiro.crypto.hash.Sha256Hash;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;


/**
 * 用户表
 *
 * @author tys
 * @email tys@mail.com
 * @date 2020-11-11 17:46:45
 */
@RestController
@RequestMapping("sys/user")
@Api(tags = "sys - 用户管理")
public class UserController {
    @Autowired
    private UserService userService;
    @Autowired
    private ISysRoleService rolesService;
    @Autowired
    private UserRoleService userRoleService;
    @Resource
    private SysUserRoleMapper sysUserRoleMapper;
    @Autowired
    private JdbcTemplate jdbcTemplate;

    @Data
    class PersonTree {
        private String userId;
        private String name;
        private String roleNames;
        private List<PersonTree> chirdrens;
    }
    /**
     * 列表
     */
    @GetMapping("personTree")
    @ApiOperation("人员树")
    public R getPersonTree () {
        String userId = LoginUserUtil.getLoginUserId() + "";
        PersonTree pt = new PersonTree();
        List<PersonTree> trees = new ArrayList<>();
        setPersonTree(userId, pt, trees);
        List<PersonTree> pts = new ArrayList<>();
        pts.add(pt);
        return R.ok().put("data", pts);
    }


    private PersonTree setPersonTree (String userId, PersonTree pt, List<PersonTree> trees) {
        UserEntity nowUser = userService.getById(userId);
        List<String> roleNames = userService.getRoleNamesByUserId(userId);
        String roleNameStr = StrUtil.join(",", roleNames);
        pt.setName(nowUser.getName());
        pt.setUserId(userId);
        pt.setRoleNames(roleNameStr);
        pt.setChirdrens(trees);
        List<UserEntity> users;
        users = userService.list(new QueryWrapper<UserEntity>().eq("parentId", userId));
        for (UserEntity user : users) {
            trees.add(setPersonTree(user.getUserId().toString(), new PersonTree(), new ArrayList<>()));
        }
        return pt;
    }

    /**
     * 列表
     */
    @GetMapping("getRoleDic")
    @ApiOperation("角色的字典(按照级别排序)")
    public R getRoleDic (){
        RolePo highRole = userService.getHighRoleUp(LoginUserUtil.getLoginUserId().toString());
        QueryWrapper<SysRole> qw = new QueryWrapper<>();
        if (highRole.getLevel() == 0) {
            qw.ge("level", -1);
            qw.ne("level", 0);
        } else {
            qw.ge("level", highRole.getLevel() + 1);
        }
        qw.orderByAsc("level");
        List<SysRole> datas = rolesService
                .list(qw);
        List<Dic> dics = datas.stream()
                .map(e -> new Dic(e.getRoleName(), e.getRoleId().toString()))
                .collect(Collectors.toList());
        return R.ok().put("data", dics);
    }


    @GetMapping("getParentUserDicByRoleId")
    @ApiOperation("获取角色的所有上级用户 （参数为角色Id的字符串用逗号隔开）")
    public R getParentOfLoginUser (String roleIds){
        String[] roleIdArr = roleIds.split(",");
        SysRole role = rolesService.getHighLevel(roleIdArr);
        List<SysRole> roles = rolesService.getParentRolesByLevel(role.getLevel());
        List<Dic> dics = new ArrayList<>();
        for (SysRole nowRole : roles) {
            List<UserEntity> users = userService.getUsersByRole(nowRole.getRoleId().toString());
            List<Dic> dic = users.stream().map(e -> new Dic(e.getName() + " (" + nowRole.getRoleName() + ") ", e.getUserId().toString())).collect(Collectors.toList());
            dics.addAll(dic);
        }
        return R.ok().put("data", dics);
    }

    /**
     * 列表
     */
    @GetMapping("list")
    @ApiOperation("用户列表")
    public R list(@RequestParam Map<String, Object> params){
        PageUtils page = userService.queryPage(params);
        return R.ok().put("data", page);
    }


    /**
     * 信息
     */
    @GetMapping("{userid}")
    @ApiOperation("用户信息")
    public R info(@PathVariable("userid") Long userid){
		UserEntity user = userService.getById(userid);
        List<SysUserRole> roles = sysUserRoleMapper.selectList(new QueryWrapper<SysUserRole>().eq("user_id", userid));
        String str = "";
        for (SysUserRole role : roles) {
            str += role.getRoleId() + ",";
        }
        user.setRoleIds(str.substring(0, str.length() - 1));
        return R.ok().put("data", user);
    }


    @GetMapping("updatePwd")
    @ApiOperation("修改密码")
    public R updatePwd(Long userId, String pwd){
        UserEntity user = userService.getById(userId);
        user.setPassword(pwd);
        userService.saveOrUpdate(user);
        return R.ok();
    }



    /**
     * 保存
     */
    @PostMapping("saveOrUpdate")
    @ApiOperation("保存或修改用户")
    public R saveOrUpdate(@RequestBody UserEntity user){
        VerifyParam.notNull(user);
        String password = new Sha256Hash(user.getPassword(), AuthConstants.SLAT_PWD).toHex();
        if (user.getUserId() == null) {
            // 新增
            //用户名唯一性校验
            int count = userService.count(new QueryWrapper<UserEntity>().eq("username", user.getUsername()));
            if (count!=0){
                throw new BusinessException(502,"用户名已存在");
            }
            user.setPassword(password);
            userService.save(user);
        } else {
            // 修改
            int count = userService.count(new QueryWrapper<UserEntity>()
                    .ne("userId", user.getUserId())
                    .eq("username", user.getUsername()));
            if (count!=0) {
                throw new BusinessException(502,"用户名已存在");
            }
            userService.saveOrUpdate(user);
        }
        // 角色
        String[] roleIds = user.getRoleIds().split(",");
        jdbcTemplate.execute("delete from sys_user_role where user_id = " + user.getUserId());
        for (String roleId : roleIds) {
            List<Map<String, Object>> maps =
                    jdbcTemplate.queryForList("select * from sys_user_role where user_id = " + user.getUserId() + " and role_id = " + roleId);
            if (maps.size() == 0) {
                jdbcTemplate.execute("insert into sys_user_role (user_id, role_id) values ("+user.getUserId()+","+roleId+")");
            }
        }
        return R.ok();
    }





    @GetMapping("delete-by-ids")
    @ApiOperation("批量删除")
    public R deletes(String userIds){
        String[] idArr = userIds.split(",");
        Arrays.stream(idArr).forEach(id -> userService.removeById(Long.parseLong(id)));
        return R.ok();
    }

    @GetMapping("delete-by-id")
    @ApiOperation("删除用户通过UserId")
    public R deleteById(String userId){
        int count = userService.count(new QueryWrapper<UserEntity>().eq("parentId", userId));
        if (count > 0) {
            throw new BusinessException(501, "当前用户存在下级用户, 不可删除");
        }
        userService.removeById(Long.parseLong(userId));
        return R.ok();
    }

    /**
     * 删除
     */
    @GetMapping("change-status")
    @ApiOperation("切换状态")
    public R changeStatus(String status, String userId){
        UserEntity user = userService.getById(Long.parseLong(userId));
        user.setStatus(status);
        userService.saveOrUpdate(user);
        return R.ok();
    }





}
